傳入參數後,藉由 switch-case
來建立一系列擁有相同親代的物件
作為入門 Design Pattern 的第一個模式,Simple Factory Method 本身不屬於「物件導向設計模式」所列的 23 個模式內,其價值在於了解「簡單」、「常用」的寫法也屬於設計模式的一種。
Simple Factory Method 的作法是:
switch-case
後決定生產哪個物件。產品親代:PETBottle
public abstract class PETBottle {
protected String smell = "";
protected String color = "";
public void setBottle(String smell, String color) {
this.smell = smell;
this.color = color;
}
public abstract String getTaste();
}
產品子代:Coke
、Water
、OrangeJuice
public class Coke extends PETBottle {
@Override
public String getTaste() {
return "這瓶可樂的顏色:" + color + ",香味是:" + smell;
}
}
public class Water extends PETBottle {
@Override
public String getTaste() {
return "這瓶水的顏色:" + color + ",香味是:" + smell;
}
}
public class OrangeJuice extends PETBottle {
@Override
public String getTaste() {
return "這瓶柳橙汁的顏色:" + color + ",香味是:" + smell;
}
}
工廠:PETBottleFactory
public class PETBottleFactory {
public static PETBottle getPETBottle(String option) throws Exception {
PETBottle bottle = null;
switch (option) {
case "coke":
bottle = new Coke();
break;
case "Water":
bottle = new Water();
break;
case "OrangeJuice":
bottle = new OrangeJuice();
break;
default:
throw new Exception("輸入錯誤");
}
return bottle;
}
}
實作:
public class PETBottleSimpleFactorySample {
public static void main(String[] args) throws Exception {
String option = "coke";
String smell = "甜甜的";
String color = "黑黑的";
PETBottle bottle = PETBottleFactory.getPETBottle(option);
bottle.setBottle(smell, color);
System.out.println(bottle.getTaste());
}
}
受限於 JavaScript 沒有虛擬型別、無法限制型別。
產品親代:PETBottle
/** @abstract */
class PETBottle {
constructor() {
this.smell = '';
this.color = '';
}
setBottle(smell, color) {
this.smell = smell;
this.color = color;
}
getTaste() { return; }
}
產品子代:Coke
、Water
、OrangeJuice
class Coke extends PETBottle {
/** @override */
getTaste() {
return "這瓶可樂的顏色:" + this.color + ",香味是:" + this.smell;
}
}
class Water extends PETBottle {
/** @override */
getTaste() {
return "這瓶水的顏色:" + this.color + ",香味是:" + this.smell;
}
}
class OrangeJuice extends PETBottle {
/** @override */
getTaste() {
return "這瓶柳橙汁的顏色:" + this.color + ",香味是:" + this.smell;
}
}
工廠:PETBottleFactory
class PETBottleFactory {
static getPETBottle(option) {
/** @type PETBottle */
let bottle = null;
switch (option) {
case "coke":
bottle = new Coke();
break;
case "Water":
bottle = new Water();
break;
case "OrangeJuice":
bottle = new OrangeJuice();
break;
default:
throw new Error("輸入錯誤");
}
return bottle;
}
}
實作:
const PETBottleSimpleFactorySample = () => {
const option = "coke";
const smell = "甜甜的";
const color = "黑黑的";
const bottle = PETBottleFactory.getPETBottle(option);
bottle.setBottle(smell, color);
console.log(bottle.getTaste());
};
PETBottleSimpleFactorySample();
Simple Factory Method 最適合當作第一個入門的模式,在於簡單好懂:
缺點則是要增加子代項目時,必須修改「生產者物件」,也就是 switch
的區塊,這點會破壞 SOLID 的 OCP,每次修改程式碼時,不該動到既有的程式碼。
因為這一點,才有後續兩個與 Factory 有關的模式。